# 读取excel数据 pandas openpyxl库
# 安装pip install pandas pip install openpyxl
import ast
import json
import os
import uuid

import pandas
import pandas as pd
import yaml

from core.global_text import g_varial


# 有excel用例，读取excel用例
# 1、执行用例的时候，假设url用的是变量{{URL}} 需要先加载context.xlsx文件中数据，渲染给hc_shop.xlsx
# 因此先加载context.xlsx文件中的数据
def load_context_from_excel(floder_path):
    try:
        # 读取excel中的context路径
        excel_file_path = os.path.join(floder_path, "context.xlsx")
        # 读取excel_file_path文件数据
        df = pd.read_excel(excel_file_path)
        # 把context中的数据放在字典中
        data = {
            "_database":{}
        }
        # 循环df中的数据
        # index 0，1,2  row是excel中具体的值
        for index, row in df.iterrows():
            # 先判断excel里面类型是不是变量，如果是，if执行
            if row["类型"] == "变量":
                # 把context里面的变量描述作为key，变量值作为value，给到data字典
                data[row["变量描述"]]=row["变量值"]
                # 再去判断数据库是不是在类型里，如果是
            elif "数据库" in row["类型"]:
                db_name = row["变量描述"] # 拿数据库名称
                # 拿到我们的数据库配置信息，用json loads转成字典
                db_config = json.loads(row["变量值"])
                # 然后用db_name作为key，db_config作为value，传到data里面的_database空字典中
                data["_database"][db_name] = db_config
                # 最后再把我们的context信息处理成字典后，传到全局变量里
            if data: g_varial().set_by_dict(data)
    except Exception as e:
        print(f"转载excel文件错误：{str(e)}")

# 读取多个excel数据
def load_excel_files(floder_path):
    # 定义一个空列表，用来装最终生成的用例
    excel_caseinfos = []
    # 调用读取context.xlsx的函数，设置全局变量
    load_context_from_excel(floder_path)
    # 定义一个空列表，装文件名称
    file_names = []
    # 拿到excel目录中所有的文件和子文件
    allfiles = os.listdir(floder_path)
    for f in allfiles:
        # 定义规则：必须以.xlsx结尾，第一个是数字，且用_分割
        if f.endswith(".xlsx") and f.split("_")[0].isdigit():
            file_number = int(f.split("_")[0])
            file_names.append((file_number,f)) # [(1,1_test_hc_shop.xlsx),(2,2_xxx.xlsx)]
    file_names.sort() # 排序
    files_names = [f[1] for f in file_names] # [1_test_hc_shop.xlsx,2_test_hc_shop.xlsx]

    # 读取用例数据 拿excel中的值作为值，拿keywords.yaml中的值作为健
    # 先拿keywords.yaml中的数据，先找到路径
    # 拿当前的路径 D:\huace_tech\inter_autotest02\day11\parse
    current_dir = os.path.abspath(os.path.dirname(__file__))
    # 再去访问上级目录 D:\huace_tech\inter_autotest02\day11
    parent_dir = os.path.dirname(current_dir)
    # 再去拼接到keywords.xlsx
    keywords_file_path = os.path.join(parent_dir,"extend/keywords.yaml")
    # 把keyword的值作为健
    keywords_info = {}
    with open(keywords_file_path,"r",encoding="utf-8") as f:
        keywords_info = yaml.full_load(f)
        # {'request_post_form_data': ['URL', 'PARAMS', 'HEADERS', 'DATA']}
        # 再去读excel用例的数据作为值
        for file_name in files_names: # 拿到我们刚才装载文件名的列表，循环取出来名称
            # 循环出来一个个具体的文件名，拼接一下具体的路径
            file_path = os.path.join(floder_path,file_name)
            # 读取excel数据
            data = pd.read_excel(file_path,sheet_name=0)
            # 把data中所有的空值设置为None
            data = data.where(data.notnull(),None)
            # 把excel转为字典
            data = data.to_dict("records")

            # 定义一条用例的变量 [{},{},{}]
            current_test_case = None
            # 对于每条用例数据处理
            for row in data:
                # 检查是不是缺失值nan 空 非nan值 有效的标题 真
                if current_test_case is not None:
                    excel_caseinfos.append(current_test_case)
                current_test_case = {"desc":row["测试用例标题"],"step":[]}
                # 处理step
                steps = {
                    row["步骤描述"]:{"关键字":row["关键字"]}
                }
                param = []
                for key,value in row.items():
                    if "参数_" in key:
                        try:
                            value = ast.literal_eval(value) # 安全解析从excel中拿到的value值 转成字典或者字符串
                        except Exception as e:
                            pass
                        param.append(value)
                # keywords.yaml作为键 param作为值
                dict_param = {k:v for k,v in zip(keywords_info[row["关键字"]],param)}
                steps[row["步骤描述"]].update(dict_param)
                current_test_case["step"].append(steps)
            if current_test_case is not None:
                excel_caseinfos.append(current_test_case)
    return excel_caseinfos

# 统一后续yaml/excel的数据格式
def excel_case_parser(folder_path):
    case_infos = []
    case_names = []
    excel_caseinfos = load_excel_files(folder_path)
    for caseinfo in excel_caseinfos:
        case_name = caseinfo.get("desc",uuid.uuid4().__str__())
        caseinfo.update({"_case_name":case_name})
        case_infos.append(caseinfo)
        case_names.append(case_name)
    return {
        "case_info":case_infos,
        "case_name":case_names
    }

if __name__ == '__main__':
    # r = readExcel(r"D:\huace_tech\inter_autotest02\day11\examples\excel_testcase\testcaselogin.xlsx")
    # print(r)
    print("a")
